/**
 * 输入验证工具
 * 提供统一的数据验证功能
 */

import { ValidationRule } from '../types/global';

export interface ValidationResult {
  isValid: boolean;
  errors: string[];
  warnings: string[];
}

export interface ValidatorOptions {
  allowEmpty?: boolean;
  trim?: boolean;
  strict?: boolean;
}

/**
 * 验证器类
 */
export class Validator {
  private rules: ValidationRule[] = [];
  private options: ValidatorOptions;

  constructor(options: ValidatorOptions = {}) {
    this.options = {
      allowEmpty: options.allowEmpty ?? false,
      trim: options.trim ?? true,
      strict: options.strict ?? false,
    };
  }

  /**
   * 添加验证规则
   */
  addRule(rule: ValidationRule): this {
    this.rules.push(rule);
    return this;
  }

  /**
   * 验证值
   */
  validate(value: unknown): ValidationResult {
    const result: ValidationResult = {
      isValid: true,
      errors: [],
      warnings: [],
    };

    // 预处理值
    let processedValue = value;
    if (typeof value === 'string' && this.options.trim) {
      processedValue = value.trim();
    }

    // 检查空值
    if (this.isEmpty(processedValue) && !this.options.allowEmpty) {
      result.isValid = false;
      result.errors.push('Value is required');
      return result;
    }

    // 应用验证规则
    for (const rule of this.rules) {
      const ruleResult = this.applyRule(processedValue, rule);
      if (!ruleResult.isValid) {
        result.isValid = false;
        result.errors.push(ruleResult.message);
      }
    }

    return result;
  }

  /**
   * 应用单个验证规则
   */
  private applyRule(value: unknown, rule: ValidationRule): { isValid: boolean; message: string } {
    switch (rule.type) {
    case 'required':
      return {
        isValid: !this.isEmpty(value),
        message: rule.message,
      };

    case 'min':
      if (typeof value === 'string') {
        return {
          isValid: value.length >= (rule.value as number),
          message: rule.message,
        };
      }
      if (typeof value === 'number') {
        return {
          isValid: value >= (rule.value as number),
          message: rule.message,
        };
      }
      return { isValid: true, message: '' };

    case 'max':
      if (typeof value === 'string') {
        return {
          isValid: value.length <= (rule.value as number),
          message: rule.message,
        };
      }
      if (typeof value === 'number') {
        return {
          isValid: value <= (rule.value as number),
          message: rule.message,
        };
      }
      return { isValid: true, message: '' };

    case 'pattern':
      if (typeof value === 'string') {
        const pattern = new RegExp(rule.value as string);
        return {
          isValid: pattern.test(value),
          message: rule.message,
        };
      }
      return { isValid: true, message: '' };

    case 'custom':
      if (rule.validator) {
        return {
          isValid: rule.validator(value),
          message: rule.message,
        };
      }
      return { isValid: true, message: '' };

    default:
      return { isValid: true, message: '' };
    }
  }

  /**
   * 检查值是否为空
   */
  private isEmpty(value: unknown): boolean {
    if (value === null || value === undefined) {
      return true;
    }
    if (typeof value === 'string') {
      return value.trim() === '';
    }
    if (Array.isArray(value)) {
      return value.length === 0;
    }
    if (typeof value === 'object') {
      return Object.keys(value).length === 0;
    }
    return false;
  }
}

/**
 * 预定义验证器
 */
export const validators = {
  /**
   * 邮箱验证器
   */
  email(): Validator {
    return new Validator()
      .addRule({
        type: 'pattern',
        value: '^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$',
        message: 'Invalid email format',
      });
  },

  /**
   * URL 验证器
   */
  url(): Validator {
    return new Validator()
      .addRule({
        type: 'pattern',
        value: '^https?:\\/\\/.+',
        message: 'Invalid URL format',
      });
  },

  /**
   * 文件路径验证器
   */
  filePath(): Validator {
    return new Validator()
      .addRule({
        type: 'custom',
        message: 'Invalid file path',
        validator: (value: unknown) => {
          if (typeof value !== 'string') return false;
          
          // 检查危险路径
          const dangerousPatterns = [
            /\.\./,  // 路径遍历
            /^\/etc/,  // 系统目录
            /^\/proc/,  // 系统目录
            /^\/sys/,  // 系统目录
            /^C:\\Windows/i,  // Windows 系统目录
            /^C:\\Program Files/i,  // Windows 程序目录
          ];

          return !dangerousPatterns.some(pattern => pattern.test(value));
        },
      });
  },

  /**
   * 插件名称验证器
   */
  pluginName(): Validator {
    return new Validator()
      .addRule({
        type: 'pattern',
        value: '^[a-zA-Z][a-zA-Z0-9_-]*$',
        message: 'Plugin name must start with letter and contain only letters, numbers, underscore and dash',
      })
      .addRule({
        type: 'min',
        value: 3,
        message: 'Plugin name must be at least 3 characters',
      })
      .addRule({
        type: 'max',
        value: 50,
        message: 'Plugin name must be at most 50 characters',
      });
  },

  /**
   * 版本号验证器
   */
  version(): Validator {
    return new Validator()
      .addRule({
        type: 'pattern',
        value: '^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9]+)?$',
        message: 'Invalid version format (expected: x.y.z or x.y.z-suffix)',
      });
  },

  /**
   * 书籍标题验证器
   */
  bookTitle(): Validator {
    return new Validator()
      .addRule({
        type: 'min',
        value: 1,
        message: 'Book title is required',
      })
      .addRule({
        type: 'max',
        value: 200,
        message: 'Book title must be at most 200 characters',
      })
      .addRule({
        type: 'custom',
        message: 'Book title contains invalid characters',
        validator: (value: unknown) => {
          if (typeof value !== 'string') return false;
          // 禁止控制字符和某些特殊字符
          return !/[\x00-\x1f\x7f<>:"/\\|?*]/.test(value);
        },
      });
  },

  /**
   * 安全字符串验证器（防止 XSS）
   */
  safeString(): Validator {
    return new Validator()
      .addRule({
        type: 'custom',
        message: 'String contains potentially dangerous content',
        validator: (value: unknown) => {
          if (typeof value !== 'string') return false;
          
          // 检查潜在的 XSS 模式
          const xssPatterns = [
            /<script/i,
            /javascript:/i,
            /on\w+\s*=/i,
            /<iframe/i,
            /<object/i,
            /<embed/i,
            /eval\s*\(/i,
            /expression\s*\(/i,
          ];

          return !xssPatterns.some(pattern => pattern.test(value));
        },
      });
  },
};

/**
 * 快速验证函数
 */
export function validateEmail(email: string): ValidationResult {
  return validators.email().validate(email);
}

export function validateUrl(url: string): ValidationResult {
  return validators.url().validate(url);
}

export function validateFilePath(path: string): ValidationResult {
  return validators.filePath().validate(path);
}

export function validatePluginName(name: string): ValidationResult {
  return validators.pluginName().validate(name);
}

export function validateVersion(version: string): ValidationResult {
  return validators.version().validate(version);
}

export function validateBookTitle(title: string): ValidationResult {
  return validators.bookTitle().validate(title);
}

export function validateSafeString(str: string): ValidationResult {
  return validators.safeString().validate(str);
}

/**
 * 批量验证
 */
export function validateObject(
  obj: Record<string, unknown>,
  rules: Record<string, Validator>,
): Record<string, ValidationResult> {
  const results: Record<string, ValidationResult> = {};

  for (const [key, validator] of Object.entries(rules)) {
    results[key] = validator.validate(obj[key]);
  }

  return results;
}

/**
 * 检查验证结果是否全部通过
 */
export function isValidationPassed(results: Record<string, ValidationResult>): boolean {
  return Object.values(results).every(result => result.isValid);
}